﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Crosland.Offline.Core;
using Crosland.Offline.Logic;
using Crosland.Offline.WinForm.Properties;
using Crosland.Util;
using Crosland.Framework.Base;

namespace Crosland.Offline.WinForm
{
    public partial class OpcionEdit : Form
    {

        SeguridadLogic logic = new SeguridadLogic();

        List<Opcion> treeItems;
        List<Opcion> treeItemsChild;

        private System.Int32 codigo;

        /// <summary>
        /// Código del registro
        /// </summary>
        public System.Int32 Codigo
        {
            get { return codigo; }
            set { codigo = value; }
        }

        private System.Int32? codigoPadre;

        /// <summary>
        /// Código del registro
        /// </summary>
        public System.Int32? CodigoPadre
        {
            get { return codigoPadre; }
            set { codigoPadre = value; }
        }

        private System.String mensaje;


        public OpcionEdit()
        {
            InitializeComponent();
        }

        private void OpcionEdit_Load(object sender, EventArgs e)
        {
            this.CargarDatos();
            this.CargarArbol();
        }

        /// <summary>
        /// Carga los datos iniciales del formulario
        /// </summary>
        protected void CargarDatos()
        {
            this.ddlEstado.DataSource = HelperClass.ListarEstados();
            this.ddlEstado.DisplayMember = Resources.CampoNombre;
            this.ddlEstado.ValueMember = Resources.CampoID;

            this.btnGrabar.Enabled = false;
            this.gbDatosRoles.Enabled = false;
        }

        /// <summary>
        /// Carga los opciones del sistema en el arbol
        /// </summary>
        protected void CargarArbol()
        {
            this.tvOpciones.Nodes.Clear();
            treeItems = this.logic.ListarOpciones();
            if (treeItems.Count > 0)
            {
                this.LlenarOpciones(null, null, this.tvOpciones);
            }

            this.tvOpciones.ExpandAll();
        }

        /// <summary>
        /// Carga en el treview, las opciones del sistema
        /// </summary>
        /// <param name="codigoPadre"></param>
        /// <param name="node"></param>
        /// <param name="tree"></param>
        public void LlenarOpciones(int? codigoPadre, TreeNode node, TreeView tree)
        {
            treeItemsChild = treeItems.FindAll(delegate(Opcion item) { return (item.IdPadre == codigoPadre); });
            treeItemsChild.Sort(delegate(Opcion a, Opcion b) { return a.NroOrden.CompareTo(b.NroOrden); });

            foreach (Opcion hijos in treeItemsChild)
            {
                TreeNode newNode = new TreeNode(hijos.DesNombre);
                newNode.Tag = hijos.ID;
                if (codigoPadre == null) tree.Nodes.Add(newNode);
                else node.Nodes.Add(newNode);
                this.LlenarOpciones(hijos.ID, newNode, null);
            }
        }

        /// <summary>
        /// Permite controlar el check del nodo
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void tvOpciones_NodeMouseClick(object sender, TreeNodeMouseClickEventArgs e)
        {
            if (e.Node.Checked)
            {
                this.codigoPadre = int.Parse(e.Node.Tag.ToString());
                this.btnNuevo.Enabled = true;
            }
            else 
            {
                this.codigoPadre = 0;
                this.btnNuevo.Enabled = false;
            }
        }

        /// <summary>
        /// Permite cargar los datos del nodo
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void tvOpciones_NodeMouseDoubleClick(object sender, TreeNodeMouseClickEventArgs e)
        {
            bool flag = (e.Node.Nodes.Count > 0) ? true : false;
            this.EditarRegistro(e.Node.Tag.ToString(), flag);
        }

        /// <summary>
        /// Permite mostrar los registros de la opcion
        /// </summary>
        /// <param name="id"></param>
        /// <param name="flagPadre"></param>
        public void EditarRegistro(string id, bool flagPadre)
        {
            this.Codigo = int.Parse(id);
            Opcion entity = this.logic.ObtenerOpcion(this.Codigo);

            this.txtCodigo.Text = id;
            this.txtDescripcion.Text = entity.DesDescripcion;
            this.txtNombre.Text = entity.DesNombre;
            this.CodigoPadre = entity.IdPadre;

            if (!flagPadre)
            {
                this.txtFormulario.Text = entity.NomFormulario;
                this.txtFormulario.Enabled = true;
            }
            else 
            {
                this.txtFormulario.Enabled = false;
            }

            this.ddlEstado.SelectedValue = entity.IndEstado;

            this.CargarListaOrden(entity.IdPadre, true);

            if (entity.NroOrden > 0)
            {
                if (this.ddlOrden.Items.Contains(entity.NroOrden.ToString()))
                {
                    this.ddlOrden.SelectedIndex = entity.NroOrden;
                }
                else
                {
                    this.ddlOrden.SelectedIndex = 0;
                }
            }
            else 
            {
                this.ddlOrden.SelectedIndex = 0;
            }

            this.btnGrabar.Enabled = true;
            this.gbDatosRoles.Enabled = true;
        }

        /// <summary>
        /// Llena la lista de opciones con los posibles ordenes
        /// </summary>
        /// <param name="idPadre"></param>
        protected void CargarListaOrden(int? idPadre, bool flagEdicion)
        {
            this.ddlOrden.Items.Clear();

            int ordenMax = this.logic.ObtenerNroElementosPorNodo(idPadre);
            ordenMax = (!flagEdicion) ? ordenMax++ : ordenMax;

            for (int i = 1; i <= ordenMax; i++)
            {
                this.ddlOrden.Items.Add(i.ToString());               
            }

            if (!flagEdicion)
            {
                this.ddlOrden.Items.Add((ordenMax + 1).ToString());
                this.ddlOrden.SelectedValue = (ordenMax + 1).ToString();                
            }
            this.ddlOrden.Items.Insert(0, Resources.TextoSeleccione);
           
        }

        /// <summary>
        /// Permite grabar un nuevo registro
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnNuevo_Click(object sender, EventArgs e)
        {
            this.NuevoRegistro();
        }

        /// <summary>
        /// Permite crear un nuevo registro
        /// </summary>
        protected void NuevoRegistro()
        {
            this.Codigo = 0;
            this.CargarListaOrden(this.CodigoPadre, false);
            this.txtCodigo.Text = string.Empty;
            this.txtDescripcion.Text = string.Empty;
            this.txtNombre.Text = string.Empty;
            this.txtFormulario.Text = string.Empty;
            this.txtFormulario.Enabled = true;
            this.ddlEstado.SelectedIndex = 0;
            this.ddlOrden.SelectedIndex = 0;
            this.btnGrabar.Enabled = true;
            this.gbDatosRoles.Enabled = true;
        }

        /// <summary>
        /// Permite grabar los datos de la opción
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnGrabar_Click(object sender, EventArgs e)
        {
            this.Grabar();
        }

        /// <summary>
        /// Permite grabar los datos de la opción
        /// </summary>
        protected void Grabar()
        {
            try
            {
                if (this.Validar())
                {
                    Opcion opcion = new Opcion();
                    opcion.ID = this.Codigo;
                    opcion.IdPadre = this.CodigoPadre;
                    opcion.DesDescripcion = this.txtDescripcion.Text;
                    opcion.DesNombre = this.txtNombre.Text;
                    opcion.IndEstado = this.ddlEstado.SelectedValue.ToString();
                    opcion.NomFormulario = this.txtFormulario.Text;
                    opcion.NroOrden = (this.ddlOrden.SelectedIndex > 0) ? int.Parse(
                        this.ddlOrden.Text) : 0;

                    this.logic.GrabarOpcion(opcion);
                    this.CargarArbol();

                    this.NuevoRegistro();
                    this.btnGrabar.Enabled = false;
                    this.gbDatosRoles.Enabled = false;
                }
                else 
                {
                    MessageBox.Show(mensaje, Resources.TituloConfirmacion, MessageBoxButtons.OK,
                       MessageBoxIcon.Warning);
                }

            }
            catch
            {
                MessageBox.Show(Resources.MsgErrorGrabar);
            }
        }

        /// <summary>
        /// Permite validar los datos del formulario
        /// </summary>
        protected bool Validar()
        {
            StringBuilder msg = new StringBuilder();

            msg.Append(Tools.ValidarCampo(this.txtNombre, "Nombre", true, TipoValidacion.Alfanumerico));
            msg.Append(Tools.ValidarCampo(this.txtFormulario, "Formulario", false, TipoValidacion.SoloLetras));
            msg.Append(Tools.ValidarCampo(this.ddlEstado, "Estado", true, TipoValidacion.Ninguno));

            if (msg.Length > 0)
            {
                mensaje = msg.ToString();
                return false;
            }

            return true;
        }


        /// <summary>
        /// Permite eliminar un registro
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void tsiEliminar_Click(object sender, EventArgs e)
        {
            DialogResult dr = MessageBox.Show(Resources.MensajeConfirmacion, Resources.TituloConfirmacion, 
                MessageBoxButtons.YesNo, MessageBoxIcon.Question, MessageBoxDefaultButton.Button1);

            if (dr == DialogResult.Yes)
            {
                this.EliminarRegistro(this.tvOpciones.SelectedNode.Tag.ToString());
            }
        }

        /// <summary>
        /// Permite eliminar el registro seleccionado
        /// </summary>
        protected void EliminarRegistro(string id)
        {
            try
            {
                Opcion opcion = this.logic.ObtenerOpcion(int.Parse(id));

                if (opcion.IdPadre != null)
                {
                    bool flag = true;
                    List<Opcion> list = this.logic.ListarOpciones();

                    foreach (Opcion item in list)
                    {
                        if (item.IdPadre == int.Parse(id))
                        {
                            flag = false;
                        }
                    }

                    if (flag)
                    {
                        this.logic.EliminarOpcion(int.Parse(id));                      
                        this.CargarArbol();
                    }
                    else
                    {
                        MessageBox.Show(Resources.MsgEliminarNodoHijo);                   
                    }
                }
                else
                {
                    MessageBox.Show(Resources.MsgNodoPrincipal);                 
                }
            }
            catch
            {
                MessageBox.Show(Resources.MsgErrorEliminar);
            }
        }

        /// <summary>
        /// Permite crear un nuevo registro
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void tsiNuevo_Click(object sender, EventArgs e)
        {
            TreeNode node = this.tvOpciones.SelectedNode;
            this.CodigoPadre = int.Parse(node.Tag.ToString());
            node.Checked = true;
            this.NuevoRegistro();
        }

        /// <summary>
        /// Permite eliminar el registro
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void tsiEditar_Click(object sender, EventArgs e)
        {
            bool flag = (this.tvOpciones.SelectedNode.Nodes.Count > 0) ? true : false;
            this.EditarRegistro(this.tvOpciones.SelectedNode.Tag.ToString(), flag);
        }

        /// <summary>
        /// Permite cerrar la venta actual
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnSalir_Click(object sender, EventArgs e)
        {
            this.Close();
        }        
    }
}
